#pragma once

#include "CoreCommon.h"
#include "MathCommon.h"
#include "Vector3.h"

LOCO_BEGIN


/// This struct is a POD
struct LOCO_CORE_API Vector4
{
	// Attributes
	float x, y, z, w;

	// Static constants
	static const Vector4 zero;
	static const Vector4 unit_x;
	static const Vector4 unit_y;
	static const Vector4 unit_z;
	static const Vector4 unit_w;
	static const Vector4 one;

	// Methods
	Vector4() = default;
	Vector4(Vector4 const& in) = default;
	Vector4(float x_val, float y_val, float z_val, float w_val);
	Vector4(Vector3 const& xyz_val, float w_val);
	Vector4(float value);

	Vector4 operator-() const;
	Vector4 operator+(Vector4 const& in) const;
	Vector4 operator-(Vector4 const& in) const;
	Vector4 operator*(Vector4 const& in) const;
	Vector4 operator/(Vector4 const& in) const;

	Vector4& operator+=(Vector4 const& in);
	Vector4& operator-=(Vector4 const& in);
	Vector4& operator*=(Vector4 const& in);
	Vector4& operator/=(Vector4 const& in);

	bool operator==(Vector4 const& in) const;
	bool operator!=(Vector4 const& in) const;
	bool operator>(Vector4 const& in) const;
	bool operator<(Vector4 const& in) const;
	bool operator>=(Vector4 const& in) const;
	bool operator<=(Vector4 const& in) const;

	float norm() const;
	float square_norm() const;

	static bool near_equal(Vector4 const& a, Vector4 const& b, float delta = DELTA);
	static float distance(Vector4 const& a, Vector4 const& b);
	static float square_distance(Vector4 const& a, Vector4 const& b);
	static float dot(Vector4 const& a, Vector4 const& b);
	static Vector4 lerp(Vector4 const& a, Vector4 const& b, float value);
	static Vector4 lerp(Vector4 const& a, Vector4 const& b, Vector4 const& value);

	// The following methods ignore the coordinate W :

	float norm3() const;
	float square_norm3() const;
	
	static float distance3(Vector4 const& a, Vector4 const& b);
	static Vector4 reflection3(Vector4 const& in, Vector4 const& normal);
	static float square_distance3(Vector4 const& a, Vector4 const& b);
	static float dot3(Vector4 const& a, Vector4 const& b);
	static Vector4 cross3(Vector4 const& a, Vector4 const& b);
};

// inline defintions
#include "Vector4.inl"

LOCO_END
